/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    subghz_phy_app.c
  * @author  x-itg
  * @brief   SubGHz PHY application implementation
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "platform.h"
#include "sys_app.h"
#include "subghz_phy_app.h"
#include "radio.h"

/* USER CODE BEGIN Includes */
#include "stm32_timer.h"
#include "stm32_seq.h"
#include "utilities_def.h"
#include "app_version.h"
#include "subghz_phy_version.h"
#include "alarm_network.h"
#include "node_config.h"
/* USER CODE END Includes */

/* External variables ---------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
// 定义状态机状态
typedef enum
{
  RADIO_IDLE,        // 射频空闲状态
  RADIO_RX,          // 射频接收状态  
  RADIO_TX,          // 射频发送状态
  RADIO_ALARM        // 报警处理状态
} RadioStates_t;

// 传感器数据结构
typedef struct
{
  uint8_t id;
  uint8_t value;
  uint32_t last_update;
} SensorData_t;
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */


#if (PAYLOAD_LEN > MAX_APP_BUFFER_SIZE)
#error "PAYLOAD_LEN must be less than or equal to MAX_APP_BUFFER_SIZE"
#endif
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
static RadioEvents_t RadioEvents;

/* USER CODE BEGIN PV */
static RadioStates_t RadioState = RADIO_RX;
static uint8_t RxBuffer[MAX_APP_BUFFER_SIZE];
static uint8_t TxBuffer[MAX_APP_BUFFER_SIZE];
static uint16_t RxBufferSize = 0;
static int8_t RssiValue = 0;
static int8_t SnrValue = 0;

// 定时器对象
static UTIL_TIMER_Object_t LedTimer;
static UTIL_TIMER_Object_t SensorQueryTimer;
static UTIL_TIMER_Object_t StatusReportTimer;

// 传感器数据
static SensorData_t sensor_data[4] = {
  {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {4, 0, 0}
};

// 系统状态


static uint8_t system_alarm_active = 0;
static uint32_t packet_rx_count = 0;
static uint32_t packet_tx_count = 0;
static uint32_t error_count = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
static void OnTxDone(void);
static void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
static void OnTxTimeout(void);
static void OnRxTimeout(void);
static void OnRxError(void);

/* USER CODE BEGIN PFP */
static void OnLedTimerEvent(void *context);
static void OnSensorQueryTimer(void *context);
static void OnStatusReportTimer(void *context);
static void ProcessReceivedPacket(uint8_t *payload, uint16_t size);
static void HandleSensorData(uint8_t sensor_id, uint8_t sensor_value);
static void SendStatusReport(void);
static void UpdateSystemStatus(void);
static void ConfigureRadio(void);
/* USER CODE END PFP */

/* Exported functions ---------------------------------------------------------*/

/**
  * @brief  SubGHz应用初始化
  */
void SubghzApp_Init(void)
{
  /* USER CODE BEGIN SubghzApp_Init_1 */
  
  // 系统启动信息
  APP_LOG(TS_OFF, VLEVEL_M, "\r\n");
  APP_LOG(TS_OFF, VLEVEL_M, "==========================================\r\n");
  APP_LOG(TS_OFF, VLEVEL_M, "  无线传感器报警网络系统启动\r\n");
  APP_LOG(TS_OFF, VLEVEL_M, "==========================================\r\n");
  
  // 显示版本信息
  APP_LOG(TS_OFF, VLEVEL_M, "应用版本: V%X.%X.%X\r\n",
         (uint8_t)(APP_VERSION_MAIN), (uint8_t)(APP_VERSION_SUB1), (uint8_t)(APP_VERSION_SUB2));
  APP_LOG(TS_OFF, VLEVEL_M, "射频模块版本: V%X.%X.%X\r\n",
         (uint8_t)(SUBGHZ_PHY_VERSION_MAIN), (uint8_t)(SUBGHZ_PHY_VERSION_SUB1), (uint8_t)(SUBGHZ_PHY_VERSION_SUB2));
  
  // 显示节点配置信息
#ifdef DEVICE_TYPE_IS_COLLECTOR
  APP_LOG(TS_OFF, VLEVEL_M, "节点类型: 采集端, ID: %d\r\n", NODE_ID);
#else
  APP_LOG(TS_OFF, VLEVEL_M, "节点类型: 报警端, ID: %d\r\n", NODE_ID);
#endif
  
  APP_LOG(TS_OFF, VLEVEL_M, "工作频率: %.1f MHz\r\n", CUSTOM_RF_FREQUENCY / 1000000.0);
  APP_LOG(TS_OFF, VLEVEL_M, "调制方式: LoRa(SF%d, BW125kHz)\r\n", LORA_SPREADING_FACTOR);
  APP_LOG(TS_OFF, VLEVEL_M, "==========================================\r\n");

  // 初始化报警网络系统
  AlarmNetwork_Init();
  
  // 初始化LED定时器 - 根据节点类型设置不同闪烁模式
  uint32_t led_period = (NODE_TYPE == NODE_TYPE_COLLECTOR) ? LED_BLINK_SLOW_MS : LED_BLINK_SLOW_MS;
  UTIL_TIMER_Create(&LedTimer, led_period, UTIL_TIMER_PERIODIC, OnLedTimerEvent, NULL);
  UTIL_TIMER_Start(&LedTimer);

  // 采集端初始化传感器查询定时器
#ifdef DEVICE_TYPE_IS_COLLECTOR
  UTIL_TIMER_Create(&SensorQueryTimer, SENSOR_QUERY_INTERVAL, UTIL_TIMER_PERIODIC, OnSensorQueryTimer, NULL);
  UTIL_TIMER_Start(&SensorQueryTimer);
#endif

  // 初始化状态报告定时器
  UTIL_TIMER_Create(&StatusReportTimer, 10000, UTIL_TIMER_PERIODIC, OnStatusReportTimer, NULL);
  UTIL_TIMER_Start(&StatusReportTimer);

  /* USER CODE END SubghzApp_Init_1 */

  // 初始化射频事件回调
  RadioEvents.TxDone = OnTxDone;
  RadioEvents.RxDone = OnRxDone;
  RadioEvents.TxTimeout = OnTxTimeout;
  RadioEvents.RxTimeout = OnRxTimeout;
  RadioEvents.RxError = OnRxError;
  Radio.Init(&RadioEvents);

  /* USER CODE BEGIN SubghzApp_Init_2 */
  
  // 配置射频参数
  ConfigureRadio();
  
  // 启动射频接收
  RadioState = RADIO_RX;
  Radio.Rx(RX_TIMEOUT_VALUE);
  
  APP_LOG(TS_ON, VLEVEL_L, "射频模块初始化完成，进入接收模式\r\n");
  
  // 注册后台处理任务
  UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_SubGHz_Phy_App_Process), UTIL_SEQ_RFU, UpdateSystemStatus);
  
  /* USER CODE END SubghzApp_Init_2 */
}

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  发送完成回调
  */
static void OnTxDone(void)
{
  /* USER CODE BEGIN OnTxDone */
  packet_tx_count++;
  APP_LOG(TS_ON, VLEVEL_L, "数据发送完成，总数: %lu\r\n", packet_tx_count);
  
  // 发送完成后立即返回接收模式
  RadioState = RADIO_RX;
  Radio.Rx(RX_TIMEOUT_VALUE);
  /* USER CODE END OnTxDone */
}

/**
  * @brief  接收完成回调
  */
static void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
{
  /* USER CODE BEGIN OnRxDone */
  RssiValue = (int8_t)rssi;
  SnrValue = snr;
  RxBufferSize = (size > MAX_APP_BUFFER_SIZE) ? MAX_APP_BUFFER_SIZE : size;
  packet_rx_count++;
  
  // 保存接收数据
  memset(RxBuffer, 0, sizeof(RxBuffer));
  memcpy(RxBuffer, payload, RxBufferSize);
  
  APP_LOG(TS_ON, VLEVEL_L, "收到数据包[%lu], 长度: %d, RSSI: %d, SNR: %d\r\n", 
         packet_rx_count, RxBufferSize, RssiValue, SnrValue);
  
  // 处理接收到的数据包
  ProcessReceivedPacket(RxBuffer, RxBufferSize);
  
  // 继续接收
  RadioState = RADIO_RX;
  Radio.Rx(RX_TIMEOUT_VALUE);
  /* USER CODE END OnRxDone */
}

/**
  * @brief  发送超时回调
  */
static void OnTxTimeout(void)
{
  /* USER CODE BEGIN OnTxTimeout */
  APP_LOG(TS_ON, VLEVEL_H, "发送超时\r\n");
  error_count++;
  
  RadioState = RADIO_RX;
  Radio.Rx(RX_TIMEOUT_VALUE);
  /* USER CODE END OnTxTimeout */
}

/**
  * @brief  接收超时回调
  */
static void OnRxTimeout(void)
{
  /* USER CODE BEGIN OnRxTimeout */
  APP_LOG(TS_ON, VLEVEL_L, "接收超时，重新启动接收\r\n");
  
  RadioState = RADIO_RX;
  Radio.Rx(RX_TIMEOUT_VALUE);
  /* USER CODE END OnRxTimeout */
}

/**
  * @brief  接收错误回调
  */
static void OnRxError(void)
{
  /* USER CODE BEGIN OnRxError */
  APP_LOG(TS_ON, VLEVEL_H, "接收错误\r\n");
  error_count++;
  
  RadioState = RADIO_RX;
  Radio.Rx(RX_TIMEOUT_VALUE);
  /* USER CODE END OnRxError */
}

/* USER CODE BEGIN PrFD */

/**
  * @brief  配置射频参数
  */
static void ConfigureRadio(void)
{
  // 设置工作频率
  Radio.SetChannel(CUSTOM_RF_FREQUENCY);
  
  // 配置发送参数
  Radio.SetTxConfig(MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
                   LORA_SPREADING_FACTOR, LORA_CODINGRATE,
                   LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                   true, 0, 0, LORA_IQ_INVERSION_ON, CUSTOM_TX_TIMEOUT_VALUE);
  
  // 配置接收参数  
  Radio.SetRxConfig(MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
                   LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
                   LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
                   0, true, 0, 0, LORA_IQ_INVERSION_ON, true);
  
  APP_LOG(TS_ON, VLEVEL_M, "射频参数配置完成: %.1fMHz SF%d BW125kHz\r\n", 
         CUSTOM_RF_FREQUENCY / 1000000.0, LORA_SPREADING_FACTOR);
}

/**
  * @brief  LED定时器事件处理
  */
static void OnLedTimerEvent(void *context)
{
  static uint8_t led_state = 0;
  
  // 基础LED闪烁
  HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
  
  // 根据系统状态控制LED3和报警指示灯
  if (system_alarm_active) {
    // 报警状态：快速闪烁
    HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin);
    
    // 报警端控制GPIOB2
#ifdef DEVICE_TYPE_IS_ALARM
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_2);
#endif
  } else {
    // 正常状态：慢速闪烁或关闭
    if (led_state == 0) {
      HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
#ifdef DEVICE_TYPE_IS_ALARM
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
#endif
    } else {
      HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET);
    }
    led_state = !led_state;
  }
}

/**
  * @brief  传感器查询定时器处理（采集端）
  */
static void OnSensorQueryTimer(void *context)
{
#ifdef DEVICE_TYPE_IS_COLLECTOR
  // 模拟传感器数据读取 - 实际应用中替换为真实的传感器读取
  for (int i = 0; i < 4; i++) {
    // 模拟随机报警触发（实际应用中根据真实传感器数据）
    uint8_t sensor_value = (HAL_GetTick() % 10000 < 100) ? 1 : 0; // 1%概率触发报警
    
    if (sensor_value != sensor_data[i].value) {
      sensor_data[i].value = sensor_value;
      sensor_data[i].last_update = HAL_GetTick();
      
      APP_LOG(TS_ON, VLEVEL_M, "传感器%d状态: %s\r\n", 
             i + 1, sensor_value ? "报警" : "正常");
      
      // 处理传感器数据
      HandleSensorData(i + 1, sensor_value);
    }
  }
#endif
}

/**
  * @brief  状态报告定时器处理
  */
static void OnStatusReportTimer(void *context)
{
  SendStatusReport();
}

/**
  * @brief  处理接收到的数据包
  */
static void ProcessReceivedPacket(uint8_t *payload, uint16_t size)
{
  // 检查是否为报警网络数据包
  if (size == sizeof(Packet_t)) {
    Packet_t *packet = (Packet_t *)payload;
    
    if (ValidatePacket(packet)) {
      APP_LOG(TS_ON, VLEVEL_M, "有效报警包: 类型%d 节点%d 事件%d 数据%d\r\n",
             packet->node_type, packet->node_id, packet->event_id, packet->data);
      
      // 交给报警网络系统处理
      if (packet->data == 1) {
        ProcessAlarmPacket(packet);
      } else {
        ProcessAckPacket(packet);
      }
    } else {
      APP_LOG(TS_ON, VLEVEL_H, "无效数据包\r\n");
    }
  } 
  // 处理传统传感器数据（向后兼容）
  else if (size >= 2) {
    uint8_t sensor_id = payload[0];
    uint8_t sensor_value = payload[1];
    
    if (sensor_id >= 1 && sensor_id <= 4) {
      APP_LOG(TS_ON, VLEVEL_L, "传统传感器数据: ID%d 值%d\r\n", sensor_id, sensor_value);
      HandleSensorData(sensor_id, sensor_value);
    }
  }
}

/**
  * @brief  处理传感器数据
  */
static void HandleSensorData(uint8_t sensor_id, uint8_t sensor_value)
{
#ifdef DEVICE_TYPE_IS_COLLECTOR
  // 采集端：触发报警网络
  if (sensor_value == 1) {
    ProcessSensorData(sensor_id, sensor_value);
  }
#else
  // 报警端：记录传感器状态
  if (sensor_id >= 1 && sensor_id <= 4) {
    sensor_data[sensor_id - 1].value = sensor_value;
    sensor_data[sensor_id - 1].last_update = HAL_GetTick();
  }
#endif
}

/**
  * @brief  发送系统状态报告
  */
static void SendStatusReport(void)
{
  // 只有采集端定期发送状态报告
#ifdef DEVICE_TYPE_IS_COLLECTOR
  if (RadioState == RADIO_RX) {
    TxBuffer[0] = 0xFE;  // 状态报告标识
    TxBuffer[1] = NODE_ID;
    TxBuffer[2] = (uint8_t)(packet_tx_count & 0xFF);
    TxBuffer[3] = (uint8_t)((packet_tx_count >> 8) & 0xFF);
    TxBuffer[4] = (uint8_t)error_count;
    
    RadioState = RADIO_TX;
    Radio.Send(TxBuffer, 5);
    
    APP_LOG(TS_ON, VLEVEL_L, "发送状态报告: 发送%lu 错误%lu\r\n", packet_tx_count, error_count);
  }
#endif
}

/**
  * @brief  更新系统状态
  */
static void UpdateSystemStatus(void)
{
  // 更新报警状态
  system_alarm_active = (State == STATE_ALARM_ACTIVE);
  
  // 根据报警状态调整LED闪烁频率
  if (system_alarm_active) {
    UTIL_TIMER_SetPeriod(&LedTimer, LED_BLINK_FAST_MS);
  } else {
    uint32_t led_period = (NODE_TYPE == NODE_TYPE_COLLECTOR) ? LED_BLINK_SLOW_MS : LED_BLINK_SLOW_MS;
    UTIL_TIMER_SetPeriod(&LedTimer, led_period);
  }
  
  // 定期显示系统状态（每30秒）
  static uint32_t last_status_log = 0;
  if (HAL_GetTick() - last_status_log > 30000) {
    last_status_log = HAL_GetTick();
    
    APP_LOG(TS_ON, VLEVEL_M, "系统状态: 接收%lu 发送%lu 错误%lu RSSI:%d\r\n",
           packet_rx_count, packet_tx_count, error_count, RssiValue);
  }
}

 

/* USER CODE END PrFD */